/**
 * 微信支付公共类
 */
var apiConfig = require('../configs/appConfig');
var security = require('../providers/security');
var common = require('../helpers/common');
var request = require('request');

var wxPayLayer = {
	prepaySign : function (appId,mchId,nonce_str,body,out_trade_no,total_fee,spbill_create_ip,notify_url,trade_type,attach,openid){
		var ret = {
			appid: appId,
			attach: attach,
			body: body,
			mch_id: mchId,
			nonce_str: nonce_str,
			notify_url: notify_url,
			out_trade_no: out_trade_no,
			spbill_create_ip: spbill_create_ip,
			total_fee: total_fee,
			openid: openid,
			trade_type: trade_type
		}
		var string = wxPayLayer.raw(ret);
		var key = apiConfig.wx.key;
		string = string + '&key=' + key;
		console.log(string);
		return security.md5(string).toUpperCase();
	},
	wxSign : function (appId,pck,timstamp,nonceStr,signType){
		var ret = {
			appId: appId,
			nonceStr: nonceStr,
			timeStamp: timstamp,
			package: pck,
			signType: signType
		};
		var string = wxPayLayer.raw(ret);
		string = string + '&key=' + apiConfig.wx.key;
		return security.md5(string).toUpperCase();
	},
	raw : function(args){
		var keys = Object.keys(args);
		keys = keys.sort()
		  var newArgs = {};
		  keys.forEach(function (key) {
		    newArgs[key] = args[key];
		  });
		  var string = '';
		  for (var k in newArgs) {
		    string += '&' + k + '=' + newArgs[k];
		  }
		  string = string.substr(1);
		  return string;
	},
	paysign : function(appId,nonce_str,pck,partnerid,prepayId,timeStamp){
		var ret = {
			appid: appId,
			noncestr: nonce_str,
			package: pck,
			partnerid: partnerid,
			prepayid: prepayId,
			timestamp: timeStamp
		}
		var string = wxPayLayer.raw(ret);
		string = string + '&key=' + apiConfig.key;
		return security.md5(string).toUpperCase();
	},
	parseBody : async (err,response,body,pf,orderNum) => {
		console.log("错误信息：" + JSON.stringify(response) + "|" + JSON.stringify(err));
		if(!err && response.statusCode == 200){
			var resJson = await common.xml2Json(body);
			console.log("解析xml: xml=> " + body + " | json=> " + JSON.stringify(resJson));
			if("SUCCESS" == resJson.xml.return_code && "SUCCESS" == resJson.xml.result_code){
				var nostr = new Date().getTime() / 1000 * 719759154 + "";
				var pck = 'prepay_id=' + resJson.xml.prepay_id;
				var time = Math.floor(new Date().getTime() / 1000);
				var clientSign = wxPayLayer.wxSign(apiConfig.WxAppId,pck,time,nostr,'MD5');
				var ret = {
						code : "SUCCESS",
						prepayid : resJson.xml.prepay_id,
						orderNum : orderNum,
						sign : clientSign,
						nonceStr : nostr,
						pck : pck,
						timestamp : time,
						partinerid : resJson.xml.mch_id,
						appId : resJson.xml.appid
				}
				console.log(ret);
				return JSON.stringify(ret);
			}else{
				var ret = {
						code : "FAIL",
						msg : resJson.xml.return_msg
				}
				return JSON.stringify(ret);
			}
		}else{
			var ret = {
					code : "FAIL",
					msg : "REQUEST INVAILD"
			}
			return JSON.stringify(ret);
		}
	},
  prePayRequest : function (orderName,orderNum,price,wxPayType,clientIP,pf,attach,openid){
		return function (cb) {
			try{
				var nonestr =  new Date().getTime();
				var appId = apiConfig.wx.appId;
				var mchId = apiConfig.wx.mchId;
				var notifyUrl = apiConfig.wx.notifyUrl;
				var sign = wxPayLayer.prepaySign(appId,mchId,nonestr,orderName,orderNum,price,clientIP,notifyUrl,wxPayType,attach,openid);
				var formData = "<xml>";
				formData += "<appid>"+ appId +"</appid>";
				formData += "<mch_id>"+ mchId +"</mch_id>";
				formData += "<nonce_str>"+ nonestr +"</nonce_str>";
				formData += "<sign>"+ sign +"</sign>";
				formData += "<body>"+ orderName +"</body>";
				formData += "<notify_url>"+ notifyUrl +"</notify_url>";
				formData += "<out_trade_no>"+ orderNum +"</out_trade_no>";
				formData += "<spbill_create_ip>"+ clientIP +"</spbill_create_ip>";
				formData += "<total_fee>"+ price +"</total_fee>";
				formData += "<trade_type>"+ wxPayType +"</trade_type>";
				formData += "<attach>"+ attach +"</attach>";
				formData += "<openid>"+ openid +"</openid>";
				formData += "</xml>";
				console.log("请求参数:" + formData);
				request({url:apiConfig.wx.unifiedOrder,method:'POST',body:formData},function(err,response,body){
					cb(null,{
						err : err,
						response: response,
						body :body
					});
					console.log(body);
				});
			}catch(e){
				//TODO handle the exception
				var ret = {
						code : "FAIL",
						msg : "PAY FAIL" + e.name + ":" + e.message
				}
				cb(null,JSON.stringify(ret));
			}
		}
	}
}


module.exports = wxPay;

function wxPay(){
	if(!(this instanceof wxPay)) return new wxPay();
}

var wx = wxPay.prototype;

//微信h5调取支付加密
wx.prePay = async (orderName,orderNum,price,wxPayType,clientIP,pf,attach,openid) => {
	/*var ret = await wxPayLayer.prePayRequest(orderName,orderNum,price,wxPayType,clientIP,pf,attach,openid);
	if (ret.code == "FAIL"){
		return ret;
	}else{
		return await wxPayLayer.parseBody(ret.err,ret.response,ret.body,pf,orderNum);
	}*/
};

/*接收通知签名*/
wx.getSignByNotify = async(args) => {
	var keys = Object.keys(args);
	 keys = keys.sort()
		  var newArgs = {};
		  keys.forEach(function (key) {
		  	if(key != "sign"){
		  		newArgs[key] = args[key];
		  	}
		  });

		  var string = '';
		  for (var k in newArgs) {
		    string += '&' + k + '=' + newArgs[k];
		  }
    string = string.substr(1);
    string = string + '&key=' + apiConfig.wx.key;
    console.log("签名串:" + string);
	return security.md5(string).toUpperCase();
}
